home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Gekkan Dennou Club 142
/
Gekkan Dennou Club - 2000.3 Vol. 142 (Japan).7z
/
Gekkan Dennou Club - 2000.3 Vol. 142 (Japan) (Track 1).bin
/
tools
/
s44play
/
s44p101s.lzh
/
preconv.mac
< prev
next >
Wrap
Text File
|
2000-01-10
|
46KB
|
1,859 lines
if .macro cond,cmd
.if cond
cmd
.endif
.endm
;----------------------------------------------------------------
Ddat reg d0 ;dn
Rpre reg d1 ;dn/an
Dfor reg d2 ;dn
Rbak reg d3 ;dn/an
Dtmp reg d4 ;dn
Dscnt reg d5 ;dn
Dtop reg d6 ;dn sq only
Adst reg a0 ;an a0に固定
Asrc reg a1 ;an a1に固定
Alim reg a2 ;an preconv内はdnでもよいがデコーダの都合でanのほうがよい
Ajmp reg a3 ;an
Rsrat reg a4 ;dn/an
Atbl reg a5 ;an
Rsone reg a6 ;dn/an const
;----------------------------------------------------------------
;データのフォーマットごとに用意しなければならないマクロ
; GET_DATA_0 モノラルのデータを1つ取り出すマクロ
; GET_DATA_1 ステレオの左のデータを1つ取り出すマクロ
; GET_DATA_2 ステレオの右のデータを1つ取り出すマクロ
;上記のマクロのパラメータ
; マクロ名 src,dat,tmp
; src ソースアドレス(アドレスレジスタ)
; デスティネーションを取り出したら,必要なサイズだけ
; ポストインクリメントする
; dat デスティネーション(データレジスタ)
; ワードサイズ,符号つき16bitのPCMを返す
; tmp テンポラリ(データレジスタ)
; ロングワードで破壊可能
;例(.s44の左のデータを取り出す)
; GET_DATA_1 .macro src,dat,tmp
; move.w (src)+,dat
; addq.l #2,src
; .endm
;----------------------------------------------------------------
;周波数変換およびPCM→FMP変換処理の制御部のマクロ
;
; PRECONV_MONO_LQ -lqでモノラル
; PRECONV_STEREO_LQ -lqでステレオ
; PRECONV_MONO_HQ -hqでモノラル
; PRECONV_STEREO_HQ -hqでステレオ
; PRECONV_MONO_SQ -sqでモノラル
; PRECONV_STEREO_SQ -sqでステレオ
;
;周波数変換およびPCM→FMP変換処理の本体のマクロ
;
; PRECONV_EQUAL_LQ -lqで周波数が同じ
; マクロ内でレジスタをロードしてからスタートする
; 終了時にAjmpに次回のエントリアドレスが設定される
; PRECONV_EXIT_EQUAL_LQ PRECONV_EQUAL_LQの出口(レジスタをセーブする)
;
; PRECONV_UP_LQ -lqで周波数が上がる
; マクロ内でレジスタをロードしてからスタートする
; 終了時にAjmpに次回のエントリアドレスが設定される
; PRECONV_EXIT_UP_LQ PRECONV_UP_LQの出口(レジスタをセーブする)
;
; PRECONV_DOWN_LQ -lqで周波数が下がる
; マクロ内でレジスタをロードしてからスタートする
; 終了時にAjmpに次回のエントリアドレスが設定される
; PRECONV_EXIT_DOWN_LQ PRECONV_DOWN_LQの出口(レジスタをセーブする)
;
; -hq,-sqも同様
;
;上記のマクロのパラメータ
; マクロ名 side
; side 0=Mono,1=StereoLeft,2=StereoRight
;
;上記のマクロはcmp.l Alim,AsrcではなくGET_DATA_?からスタートするので,
;必要ならばバッファの初期設定(最初のブロックのADPCM→PCM変換など)を行うマクロ
;START_PRECONV_BUFFERを定義し,ここでAsrc,Alimなどの設定を行うこと.
;ステレオの場合は必ずSTART_PRECONV_BUFFERでAsrcのリワインドを行うこと.
;バッファ内のデータの前処理が必要でSTART_PRECONV_BUFFERですべてのデータを
;一度に変換できない場合は,マクロLOOP_PRECONV_BUFFERを定義してここで次のデータを
;用意し,jmp (Ajmp)によって変換を継続すること.
;変換を継続する必要がなければLOOP_PRECONV_BUFFERは空でよい.
;
;START_PRECONV_BUFFER side
; side 0=Mono,1=StereoLeft,2=StereoRight
; Asrc,Alim,Adstの設定を行う(rightのときここでやる必要がある)
; rightのAdstはleftと同じ値を返すこと
;
;LOOP_PRECONV_BUFFER side
; side 0=Mono,1=StereoLeft,2=StereoRight
; 周波数変換およびPCM→FMP変換処理の前にADPCMなどのデコードが必要な場合,
; ロードしたすべてのデータをSTART_PRECONV_BUFFERまでにデコードすることが
; できない場合がある.
; その場合,LOOP_PRECONV_BUFFERで次のデータをデコードして変換処理を継続する
; ことができるようになっている.
; 継続はjmp (Ajmp)で行わなければならない.
; 変換を継続する必要がなければ,LOOP_PRECONV_BUFFERは空でよい.
; ロードしたデータの変換が終わったあとのレジスタ(Ajmpなど)のセーブは,
; LOOP_PRECONV_BUFFERの後に実行されるPRECONV_EXIT_~で行われる.
;----------------------------------------------------------------
;モノラル<Low Quality>
PRECONV_MONO_LQ .macro
lea.l pcm2tl_table+32768,Atbl
cmpi.l #65536,speed_rate
blo @up ;間隔が縮む→周波数が上がる
bhi @down ;間隔が伸びる→周波数が下がる
;間隔が同じ→周波数が同じ
@equal:
START_PRECONV_BUFFER 0
PRECONV_EQUAL_LQ 0
LOOP_PRECONV_BUFFER 0
PRECONV_EXIT_EQUAL_LQ 0
bra @done
;間隔が縮む→周波数が上がる
@up:
START_PRECONV_BUFFER 0
PRECONV_UP_LQ 0
LOOP_PRECONV_BUFFER 0
PRECONV_EXIT_UP_LQ 0
bra @done
;間隔が伸びる→周波数が下がる
@down:
START_PRECONV_BUFFER 0
PRECONV_DOWN_LQ 0
LOOP_PRECONV_BUFFER 0
PRECONV_EXIT_DOWN_LQ 0
bra @done
@done:
.endm
;----------------------------------------------------------------
;モノラル<High Quality>
PRECONV_MONO_HQ .macro
lea.l pcm2tl_table+32768,Atbl
cmpi.l #65536,speed_rate
bhi @down ;間隔が伸びる→周波数が下がる
;間隔が同じ→周波数が同じ
;間隔が縮む→周波数が上がる
@up:
START_PRECONV_BUFFER 0
PRECONV_UP_HQ 0
LOOP_PRECONV_BUFFER 0
PRECONV_EXIT_UP_HQ 0
bra @done
;間隔が伸びる→周波数が下がる
@down:
START_PRECONV_BUFFER 0
PRECONV_DOWN_HQ 0
LOOP_PRECONV_BUFFER 0
PRECONV_EXIT_DOWN_HQ 0
bra @done
@done:
.endm
;----------------------------------------------------------------
;モノラル<Super Quality>
PRECONV_MONO_SQ .macro
lea.l pcm2tl_table+32768,Atbl
cmpi.l #65536,speed_rate
bhi @down ;間隔が伸びる→周波数が下がる
;間隔が同じ→周波数が同じ
;間隔が縮む→周波数が上がる
@up:
START_PRECONV_BUFFER 0
PRECONV_UP_SQ 0
LOOP_PRECONV_BUFFER 0
PRECONV_EXIT_UP_SQ 0
bra @done
;間隔が伸びる→周波数が下がる
@down:
START_PRECONV_BUFFER 0
PRECONV_DOWN_SQ 0
LOOP_PRECONV_BUFFER 0
PRECONV_EXIT_DOWN_SQ 0
bra @done
@done:
.endm
;----------------------------------------------------------------
;ステレオ<Low Quality>
PRECONV_STEREO_LQ .macro
lea.l pcm2tl_table+32768,Atbl
cmpi.l #65536,speed_rate
blo @up ;間隔が縮む→周波数が上がる
bhi @down ;間隔が伸びる→周波数が下がる
;間隔が同じ→周波数が同じ
@equal:
START_PRECONV_BUFFER 1
move.w preconv_rest_1,Dtmp
bpl @f
move.b Dtmp,(Adst)+
addq.l #1,Adst
@@:
PRECONV_EQUAL_LQ 1
LOOP_PRECONV_BUFFER 1
PRECONV_EXIT_EQUAL_LQ 1
move.l Adst,-(sp) ;leftのdstの末尾+2
START_PRECONV_BUFFER 2
addq.l #1,Adst ;dst
move.w preconv_rest_2,Dtmp
bpl @f
move.b Dtmp,(Adst)+
addq.l #1,Adst
@@:
PRECONV_EQUAL_LQ 2
LOOP_PRECONV_BUFFER 2
PRECONV_EXIT_EQUAL_LQ 2
subq.l #1,Adst ;rightのdstの末尾+1=dstの末尾+1
lea.l preconv_rest_1,a3
cmpa.l (sp)+,Adst ;(rightのdstの末尾+1)-(leftのdstの末尾+2)
blo 1f ;leftが長い
bhi 2f ;rightが長い
sf.b (a3)+ ;left繰り越しなし
sf.b (1,a3) ;right繰り越しなし
bra @done
1: st.b (a3)+ ;left繰り越しあり
move.b (Adst),(a3)+ ;left繰り越しデータ
sf.b (a3) ;right繰り越しなし
bra @done
2: sf.b (a3)+ ;left繰り越しなし
addq.l #1,a3
st.b (a3)+ ;right繰り越しあり
move.b -(Adst),(a3) ;right繰り越しデータ
subq.l #1,Adst
bra @done
;間隔が縮む→周波数が上がる
@up:
START_PRECONV_BUFFER 1
move.w preconv_rest_1,Dtmp
bpl @f
move.b Dtmp,(Adst)+
addq.l #1,Adst
@@:
PRECONV_UP_LQ 1
LOOP_PRECONV_BUFFER 1
PRECONV_EXIT_UP_LQ 1
move.l Adst,-(sp) ;leftのdstの末尾+2
START_PRECONV_BUFFER 2
addq.l #1,Adst ;dst
move.w preconv_rest_2,Dtmp
bpl @f
move.b Dtmp,(Adst)+
addq.l #1,Adst
@@:
PRECONV_UP_LQ 2
LOOP_PRECONV_BUFFER 2
PRECONV_EXIT_UP_LQ 2
subq.l #1,Adst ;rightのdstの末尾+1=dstの末尾+1
lea.l preconv_rest_1,a3
cmpa.l (sp)+,Adst ;(rightのdstの末尾+1)-(leftのdstの末尾+2)
blo 1f ;leftが長い
bhi 2f ;rightが長い
sf.b (a3)+ ;left繰り越しなし
sf.b (1,a3) ;right繰り越しなし
bra @done
1: st.b (a3)+ ;left繰り越しあり
move.b (Adst),(a3)+ ;left繰り越しデータ
sf.b (a3) ;right繰り越しなし
bra @done
2: sf.b (a3)+ ;left繰り越しなし
addq.l #1,a3
st.b (a3)+ ;right繰り越しあり
move.b -(Adst),(a3) ;right繰り越しデータ
subq.l #1,Adst
bra @done
;間隔が伸びる→周波数が下がる
@down:
START_PRECONV_BUFFER 1
move.w preconv_rest_1,Dtmp
bpl @f
move.b Dtmp,(Adst)+
addq.l #1,Adst
@@:
PRECONV_DOWN_LQ 1
LOOP_PRECONV_BUFFER 1
PRECONV_EXIT_DOWN_LQ 1
move.l Adst,-(sp) ;leftのdstの末尾+2
START_PRECONV_BUFFER 2
addq.l #1,Adst ;dst
move.w preconv_rest_2,Dtmp
bpl @f
move.b Dtmp,(Adst)+
addq.l #1,Adst
@@:
PRECONV_DOWN_LQ 2
LOOP_PRECONV_BUFFER 2
PRECONV_EXIT_DOWN_LQ 2
subq.l #1,Adst ;rightのdstの末尾+1=dstの末尾+1
lea.l preconv_rest_1,a3
cmpa.l (sp)+,Adst ;(rightのdstの末尾+1)-(leftのdstの末尾+2)
blo 1f ;leftが長い
bhi 2f ;rightが長い
sf.b (a3)+ ;left繰り越しなし
sf.b (1,a3) ;right繰り越しなし
bra @done
1: st.b (a3)+ ;left繰り越しあり
move.b (Adst),(a3)+ ;left繰り越しデータ
sf.b (a3) ;right繰り越しなし
bra @done
2: sf.b (a3)+ ;left繰り越しなし
addq.l #1,a3
st.b (a3)+ ;right繰り越しあり
move.b -(Adst),(a3) ;right繰り越しデータ
subq.l #1,Adst
bra @done
@done:
.endm
;----------------------------------------------------------------
;ステレオ<High Quality>
PRECONV_STEREO_HQ .macro
lea.l pcm2tl_table+32768,Atbl
cmpi.l #65536,speed_rate
bhi @down ;間隔が伸びる→周波数が下がる
;間隔が同じ→周波数が同じ
;間隔が縮む→周波数が上がる
@up:
START_PRECONV_BUFFER 1
move.w preconv_rest_1,Dtmp
bpl @f
move.b Dtmp,(Adst)+
addq.l #1,Adst
@@:
PRECONV_UP_HQ 1
LOOP_PRECONV_BUFFER 1
PRECONV_EXIT_UP_HQ 1
move.l Adst,-(sp) ;leftのdstの末尾+2
START_PRECONV_BUFFER 2
addq.l #1,Adst ;dst
move.w preconv_rest_2,Dtmp
bpl @f
move.b Dtmp,(Adst)+
addq.l #1,Adst
@@:
PRECONV_UP_HQ 2
LOOP_PRECONV_BUFFER 2
PRECONV_EXIT_UP_HQ 2
subq.l #1,Adst ;rightのdstの末尾+1=dstの末尾+1
lea.l preconv_rest_1,a3
cmpa.l (sp)+,Adst ;(rightのdstの末尾+1)-(leftのdstの末尾+2)
blo 1f ;leftが長い
bhi 2f ;rightが長い
sf.b (a3)+ ;left繰り越しなし
sf.b (1,a3) ;right繰り越しなし
bra @done
1: st.b (a3)+ ;left繰り越しあり
move.b (Adst),(a3)+ ;left繰り越しデータ
sf.b (a3) ;right繰り越しなし
bra @done
2: sf.b (a3)+ ;left繰り越しなし
addq.l #1,a3
st.b (a3)+ ;right繰り越しあり
move.b -(Adst),(a3) ;right繰り越しデータ
subq.l #1,Adst
bra @done
;間隔が伸びる→周波数が下がる
@down:
START_PRECONV_BUFFER 1
move.w preconv_rest_1,Dtmp
bpl @f
move.b Dtmp,(Adst)+
addq.l #1,Adst
@@:
PRECONV_DOWN_HQ 1
LOOP_PRECONV_BUFFER 1
PRECONV_EXIT_DOWN_HQ 1
move.l Adst,-(sp) ;leftのdstの末尾+2
START_PRECONV_BUFFER 2
addq.l #1,Adst ;dst
move.w preconv_rest_2,Dtmp
bpl @f
move.b Dtmp,(Adst)+
addq.l #1,Adst
@@:
PRECONV_DOWN_HQ 2
LOOP_PRECONV_BUFFER 2
PRECONV_EXIT_DOWN_HQ 2
subq.l #1,Adst ;rightのdstの末尾+1=dstの末尾+1
lea.l preconv_rest_1,a3
cmpa.l (sp)+,Adst ;(rightのdstの末尾+1)-(leftのdstの末尾+2)
blo 1f ;leftが長い
bhi 2f ;rightが長い
sf.b (a3)+ ;left繰り越しなし
sf.b (1,a3) ;right繰り越しなし
bra @done
1: st.b (a3)+ ;left繰り越しあり
move.b (Adst),(a3)+ ;left繰り越しデータ
sf.b (a3) ;right繰り越しなし
bra @done
2: sf.b (a3)+ ;left繰り越しなし
addq.l #1,a3
st.b (a3)+ ;right繰り越しあり
move.b -(Adst),(a3) ;right繰り越しデータ
subq.l #1,Adst
bra @done
@done:
.endm
;----------------------------------------------------------------
;ステレオ<Super Quality>
PRECONV_STEREO_SQ .macro
lea.l pcm2tl_table+32768,Atbl
cmpi.l #65536,speed_rate
bhi @down ;間隔が伸びる→周波数が下がる
;間隔が同じ→周波数が同じ
;間隔が縮む→周波数が上がる
@up:
START_PRECONV_BUFFER 1
move.w preconv_rest_1,Dtmp
bpl @f
move.b Dtmp,(Adst)+
addq.l #1,Adst
@@:
PRECONV_UP_SQ 1
LOOP_PRECONV_BUFFER 1
PRECONV_EXIT_UP_SQ 1
move.l Adst,-(sp) ;leftのdstの末尾+2
START_PRECONV_BUFFER 2
addq.l #1,Adst ;dst
move.w preconv_rest_2,Dtmp
bpl @f
move.b Dtmp,(Adst)+
addq.l #1,Adst
@@:
PRECONV_UP_SQ 2
LOOP_PRECONV_BUFFER 2
PRECONV_EXIT_UP_SQ 2
subq.l #1,Adst ;rightのdstの末尾+1=dstの末尾+1
lea.l preconv_rest_1,a3
cmpa.l (sp)+,Adst ;(rightのdstの末尾+1)-(leftのdstの末尾+2)
blo 1f ;leftが長い
bhi 2f ;rightが長い
sf.b (a3)+ ;left繰り越しなし
sf.b (1,a3) ;right繰り越しなし
bra @done
1: st.b (a3)+ ;left繰り越しあり
move.b (Adst),(a3)+ ;left繰り越しデータ
sf.b (a3) ;right繰り越しなし
bra @done
2: sf.b (a3)+ ;left繰り越しなし
addq.l #1,a3
st.b (a3)+ ;right繰り越しあり
move.b -(Adst),(a3) ;right繰り越しデータ
subq.l #1,Adst
bra @done
;間隔が伸びる→周波数が下がる
@down:
START_PRECONV_BUFFER 1
move.w preconv_rest_1,Dtmp
bpl @f
move.b Dtmp,(Adst)+
addq.l #1,Adst
@@:
PRECONV_DOWN_SQ 1
LOOP_PRECONV_BUFFER 1
PRECONV_EXIT_DOWN_SQ 1
move.l Adst,-(sp) ;leftのdstの末尾+2
START_PRECONV_BUFFER 2
addq.l #1,Adst ;dst
move.w preconv_rest_2,Dtmp
bpl @f
move.b Dtmp,(Adst)+
addq.l #1,Adst
@@:
PRECONV_DOWN_SQ 2
LOOP_PRECONV_BUFFER 2
PRECONV_EXIT_DOWN_SQ 2
subq.l #1,Adst ;rightのdstの末尾+1=dstの末尾+1
lea.l preconv_rest_1,a3
cmpa.l (sp)+,Adst ;(rightのdstの末尾+1)-(leftのdstの末尾+2)
blo 1f ;leftが長い
bhi 2f ;rightが長い
sf.b (a3)+ ;left繰り越しなし
sf.b (1,a3) ;right繰り越しなし
bra @done
1: st.b (a3)+ ;left繰り越しあり
move.b (Adst),(a3)+ ;left繰り越しデータ
sf.b (a3) ;right繰り越しなし
bra @done
2: sf.b (a3)+ ;left繰り越しなし
addq.l #1,a3
st.b (a3)+ ;right繰り越しあり
move.b -(Adst),(a3) ;right繰り越しデータ
subq.l #1,Adst
bra @done
@done:
.endm
;----------------------------------------------------------------
;----------------------------------------------------------------
;<Low Quality>
;間隔が同じ→周波数が同じ
; side 0=Mono,1=StereoLeft,2=StereoRight
;Ddat dn
;Rpre dn/an
;Dtmp dn
;Atbl an
;Asrc an
;Adst an
;Ajmp an
;Alim dn/an
PRECONV_EQUAL_LQ .macro side
move.w preconv_pre_&side,Rpre
move.l preconv_jmp_&side,Ajmp
move.l Ajmp,Dtmp
beq @spp
jmp (Ajmp)
@npp: move.b #$7F,(Adst)+
if side,<addq.l #1,Adst>
bra @vpp
@dpp: move.b (Atbl,Rpre.w),(Adst)+
if side,<addq.l #1,Adst>
@vpp: move.w Ddat,Rpre
cmp.l Alim,Asrc
bhs @epp
@spp: GET_DATA_&side Asrc,Ddat,Dtmp
bgt @dpp
beq @dpm
move.w Ddat,Dtmp
add.w Rpre,Dtmp
blt @xmm
@dpm: move.b (Atbl,Rpre.w),(Adst)+
if side,<addq.l #1,Adst>
@vpm: move.w Ddat,Rpre
cmp.l Alim,Asrc
bhs @epm
@spm: GET_DATA_&side Asrc,Ddat,Dtmp
bgt @npp
beq @npz
@xmm: st.b (Adst)+
if side,<addq.l #1,Adst>
bra @vmm
@npz: move.b #$7F,(Adst)+
if side,<addq.l #1,Adst>
bra @vpm
@nmm: move.b #$7F,(Adst)+
if side,<addq.l #1,Adst>
bra @vmm
@dmm: move.b (Atbl,Rpre.w),(Adst)+
if side,<addq.l #1,Adst>
@vmm: move.w Ddat,Rpre
cmp.l Alim,Asrc
bhs @emm
@smm: GET_DATA_&side Asrc,Ddat,Dtmp
blt @dmm
beq @dmp
move.w Ddat,Dtmp
add.w Rpre,Dtmp
bgt @xpp
@dmp: move.b (Atbl,Rpre.w),(Adst)+
if side,<addq.l #1,Adst>
@vmp: move.w Ddat,Rpre
cmp.l Alim,Asrc
bhs @emp
@smp: GET_DATA_&side Asrc,Ddat,Dtmp
blt @nmm
beq @nmz
@xpp: st.b (Adst)+
if side,<addq.l #1,Adst>
bra @vpp
@nmz: move.b #$7F,(Adst)+
if side,<addq.l #1,Adst>
bra @vmp
@epp: lea.l (@spp,pc),Ajmp
bra @done
@epm: lea.l (@spm,pc),Ajmp
bra @done
@emm: lea.l (@smm,pc),Ajmp
bra @done
@emp: lea.l (@smp,pc),Ajmp
bra @done
@done:
.endm
PRECONV_EXIT_EQUAL_LQ .macro side
move.l Ajmp,preconv_jmp_&side
move.w Rpre,preconv_pre_&side
.endm
;----------------------------------------------------------------
;<Low Quality>
;間隔が縮む→周波数が上がる
; side 0=Mono,1=StereoLeft,2=StereoRight
;Ddat dn
;Rpre dn/an
;Dtmp dn
;Dscnt dn
;Atbl an
;Asrc an
;Adst an
;Ajmp an
;Rsrat dn/an
;Alim dn/an
PRECONV_UP_LQ .macro side
move.w preconv_scnt_&side+2,Dscnt
move.w preconv_pre_&side,Rpre
move.l preconv_jmp_&side,Ajmp
move.w speed_rate+2,Rsrat
move.l Ajmp,Dtmp
beq @spp
jmp (Ajmp)
@npp: move.b #$7F,(Adst)+
if side,<addq.l #1,Adst>
bra @vpp
@dpp: move.b (Atbl,Rpre.w),(Adst)+
if side,<addq.l #1,Adst>
@vpp: add.w Rsrat,Dscnt
bcc 10f
move.w Ddat,Rpre
cmp.l Alim,Asrc
bhs @epp
@spp: GET_DATA_&side Asrc,Ddat,Dtmp
10: tst.w Ddat
bgt @dpp
beq @dpm
move.w Ddat,Dtmp
add.w Rpre,Dtmp
blt @xmm
@dpm: move.b (Atbl,Rpre.w),(Adst)+
if side,<addq.l #1,Adst>
@vpm: add.w Rsrat,Dscnt
bcc 10f
move.w Ddat,Rpre
cmp.l Alim,Asrc
bhs @epm
@spm: GET_DATA_&side Asrc,Ddat,Dtmp
10: tst.w Ddat
bgt @npp
beq @npz
@xmm: st.b (Adst)+
if side,<addq.l #1,Adst>
bra @vmm
@npz: move.b #$7F,(Adst)+
if side,<addq.l #1,Adst>
bra @vpm
@nmm: move.b #$7F,(Adst)+
if side,<addq.l #1,Adst>
bra @vmm
@dmm: move.b (Atbl,Rpre.w),(Adst)+
if side,<addq.l #1,Adst>
@vmm: add.w Rsrat,Dscnt
bcc 10f
move.w Ddat,Rpre
cmp.l Alim,Asrc
bhs @emm
@smm: GET_DATA_&side Asrc,Ddat,Dtmp
10: tst.w Ddat
blt @dmm
beq @dmp
move.w Ddat,Dtmp
add.w Rpre,Dtmp
bgt @xpp
@dmp: move.b (Atbl,Rpre.w),(Adst)+
if side,<addq.l #1,Adst>
@vmp: add.w Rsrat,Dscnt
bcc 10f
move.w Ddat,Rpre
cmp.l Alim,Asrc
bhs @emp
@smp: GET_DATA_&side Asrc,Ddat,Dtmp
10: tst.w Ddat
blt @nmm
beq @nmz
@xpp: st.b (Adst)+
if side,<addq.l #1,Adst>
bra @vpp
@nmz: move.b #$7F,(Adst)+
if side,<addq.l #1,Adst>
bra @vmp
@epp: lea.l (@spp,pc),Ajmp
bra @done
@epm: lea.l (@spm,pc),Ajmp
bra @done
@emm: lea.l (@smm,pc),Ajmp
bra @done
@emp: lea.l (@smp,pc),Ajmp
bra @done
@done:
.endm
PRECONV_EXIT_UP_LQ .macro side
move.l Ajmp,preconv_jmp_&side
move.w Rpre,preconv_pre_&side
move.w Dscnt,preconv_scnt_&side+2
.endm
;----------------------------------------------------------------
;<Low Quality>
;間隔が伸びる→周波数が下がる
; side 0=Mono,1=StereoLeft,2=StereoRight
;Ddat dn
;Rpre dn/an
;Dtmp dn
;Dscnt dn
;Atbl an
;Asrc an
;Adst an
;Ajmp an
;Rsone dn/an const
;Rsrat dn/an
;Alim dn/an
PRECONV_DOWN_LQ .macro side
move.l preconv_scnt_&side,Dscnt
move.w preconv_pre_&side,Rpre
move.l preconv_jmp_&side,Ajmp
move.l speed_rate,Rsrat
move.l #65536,Rsone
move.l Ajmp,Dtmp
beq @spp
jmp (Ajmp)
@npp: move.b #$7F,(Adst)+
if side,<addq.l #1,Adst>
bra @vpp
@dpp: move.b (Atbl,Rpre.w),(Adst)+
if side,<addq.l #1,Adst>
@vpp: move.w Ddat,Rpre
10: cmp.l Alim,Asrc
bhs @epp
@spp: GET_DATA_&side Asrc,Ddat,Dtmp
sub.l Rsone,Dscnt
bpl 10b
add.l Rsrat,Dscnt
tst.w Ddat
bgt @dpp
beq @dpm
move.w Ddat,Dtmp
add.w Rpre,Dtmp
blt @xmm
@dpm: move.b (Atbl,Rpre.w),(Adst)+
if side,<addq.l #1,Adst>
@vpm: move.w Ddat,Rpre
10: cmp.l Alim,Asrc
bhs @epm
@spm: GET_DATA_&side Asrc,Ddat,Dtmp
sub.l Rsone,Dscnt
bpl 10b
add.l Rsrat,Dscnt
tst.w Ddat
bgt @npp
beq @npz
@xmm: st.b (Adst)+
if side,<addq.l #1,Adst>
bra @vmm
@npz: move.b #$7F,(Adst)+
if side,<addq.l #1,Adst>
bra @vpm
@nmm: move.b #$7F,(Adst)+
if side,<addq.l #1,Adst>
bra @vmm
@dmm: move.b (Atbl,Rpre.w),(Adst)+
if side,<addq.l #1,Adst>
@vmm: move.w Ddat,Rpre
10: cmp.l Alim,Asrc
bhs @emm
@smm: GET_DATA_&side Asrc,Ddat,Dtmp
sub.l Rsone,Dscnt
bpl 10b
add.l Rsrat,Dscnt
tst.w Ddat
blt @dmm
beq @dmp
move.w Ddat,Dtmp
add.w Rpre,Dtmp
bgt @xpp
@dmp: move.b (Atbl,Rpre.w),(Adst)+
if side,<addq.l #1,Adst>
@vmp: move.w Ddat,Rpre
10: cmp.l Alim,Asrc
bhs @emp
@smp: GET_DATA_&side Asrc,Ddat,Dtmp
sub.l Rsone,Dscnt
bpl 10b
add.l Rsrat,Dscnt
tst.w Ddat
blt @nmm
beq @nmz
@xpp: st.b (Adst)+
if side,<addq.l #1,Adst>
bra @vpp
@nmz: move.b #$7F,(Adst)+
if side,<addq.l #1,Adst>
bra @vmp
@epp: lea.l (@spp,pc),Ajmp
bra @done
@epm: lea.l (@spm,pc),Ajmp
bra @done
@emm: lea.l (@smm,pc),Ajmp
bra @done
@emp: lea.l (@smp,pc),Ajmp
bra @done
@done:
.endm
PRECONV_EXIT_DOWN_LQ .macro side
move.l Ajmp,preconv_jmp_&side
move.w Rpre,preconv_pre_&side
move.l Dscnt,preconv_scnt_&side
.endm
;----------------------------------------------------------------
;----------------------------------------------------------------
;<High Quality>
;間隔が縮む→周波数が上がる
; side 0=Mono,1=StereoLeft,2=StereoRight
;Ddat dn
;Dfor dn
;Rpre dn/an
;Rbak dn/an
;Dtmp dn
;Dscnt dn
;Atbl an
;Asrc an
;Adst an
;Ajmp an
;Rsrat dn/an
;Alim dn/an
PRECONV_UP_HQ .macro side
move.w preconv_for_&side,Dfor
move.w preconv_bak_&side,Rbak
move.w preconv_scnt_&side+2,Dscnt
move.w preconv_pre_&side,Rpre
move.l preconv_jmp_&side,Ajmp
move.w speed_rate+2,Rsrat
move.l Ajmp,Dtmp
beq @spp
jmp (Ajmp)
@npp: move.b #$7F,(Adst)+
if side,<addq.l #1,Adst>
bra @vpp
@dpp: move.b (Atbl,Rpre.w),(Adst)+
if side,<addq.l #1,Adst>
@vpp: move.w Ddat,Rpre
add.w Rsrat,Dscnt
bcc 10f
move.w Dfor,Rbak
cmp.l Alim,Asrc
bhs @epp
@spp: GET_DATA_&side Asrc,Dfor,Dtmp
add.w #$8000,Dfor
10: move.w Dfor,Ddat ;Dfor>=Rbak Dfor<Rbak
sub.w Rbak,Ddat ;Dfor-Rbak Dfor-Rbak+65536
subx.w Dtmp,Dtmp ;0 -1
mulu.w Dscnt,Ddat ;(Dfor-Rbak)*RATE*65536 (Dfor-Rbak+65536)*RATE*65536
and.w Dscnt,Dtmp ;0 RATE*65536
swap.w Ddat ;(Dfor-Rbak)*RATE (Dfor-Rbak+65536)*RATE
sub.w Dtmp,Ddat ;(Dfor-Rbak)*RATE (Dfor-Rbak)*RATE
add.w Rbak,Ddat ;Rbak+(Dfor-Rbak)*RATE Rbak+(Dfor-Rbak)*RATE
sub.w #$8000,Ddat
bhi @dpp
beq @dpm
move.w Ddat,Dtmp
add.w Rpre,Dtmp
blt @xmm
@dpm: move.b (Atbl,Rpre.w),(Adst)+
if side,<addq.l #1,Adst>
@vpm: move.w Ddat,Rpre
add.w Rsrat,Dscnt
bcc 10f
move.w Dfor,Rbak
cmp.l Alim,Asrc
bhs @epm
@spm: GET_DATA_&side Asrc,Dfor,Dtmp
add.w #$8000,Dfor
10: move.w Dfor,Ddat ;Dfor>=Rbak Dfor<Rbak
sub.w Rbak,Ddat ;Dfor-Rbak Dfor-Rbak+65536
subx.w Dtmp,Dtmp ;0 -1
mulu.w Dscnt,Ddat ;(Dfor-Rbak)*RATE*65536 (Dfor-Rbak+65536)*RATE*65536
and.w Dscnt,Dtmp ;0 RATE*65536
swap.w Ddat ;(Dfor-Rbak)*RATE (Dfor-Rbak+65536)*RATE
sub.w Dtmp,Ddat ;(Dfor-Rbak)*RATE (Dfor-Rbak)*RATE
add.w Rbak,Ddat ;Rbak+(Dfor-Rbak)*RATE Rbak+(Dfor-Rbak)*RATE
sub.w #$8000,Ddat
bhi @npp
beq @npz
@xmm: st.b (Adst)+
if side,<addq.l #1,Adst>
bra @vmm
@npz: move.b #$7F,(Adst)+
if side,<addq.l #1,Adst>
bra @vpm
@nmm: move.b #$7F,(Adst)+
if side,<addq.l #1,Adst>
bra @vmm
@dmm: move.b (Atbl,Rpre.w),(Adst)+
if side,<addq.l #1,Adst>
@vmm: move.w Ddat,Rpre
add.w Rsrat,Dscnt
bcc 10f
move.w Dfor,Rbak
cmp.l Alim,Asrc
bhs @emm
@smm: GET_DATA_&side Asrc,Dfor,Dtmp
add.w #$8000,Dfor
10: move.w Dfor,Ddat ;Dfor>=Rbak Dfor<Rbak
sub.w Rbak,Ddat ;Dfor-Rbak Dfor-Rbak+65536
subx.w Dtmp,Dtmp ;0 -1
mulu.w Dscnt,Ddat ;(Dfor-Rbak)*RATE*65536 (Dfor-Rbak+65536)*RATE*65536
and.w Dscnt,Dtmp ;0 RATE*65536
swap.w Ddat ;(Dfor-Rbak)*RATE (Dfor-Rbak+65536)*RATE
sub.w Dtmp,Ddat ;(Dfor-Rbak)*RATE (Dfor-Rbak)*RATE
add.w Rbak,Ddat ;Rbak+(Dfor-Rbak)*RATE Rbak+(Dfor-Rbak)*RATE
sub.w #$8000,Ddat
blo @dmm
beq @dmp
move.w Ddat,Dtmp
add.w Rpre,Dtmp
bgt @xpp
@dmp: move.b (Atbl,Rpre.w),(Adst)+
if side,<addq.l #1,Adst>
@vmp: move.w Ddat,Rpre
add.w Rsrat,Dscnt
bcc 10f
move.w Dfor,Rbak
cmp.l Alim,Asrc
bhs @emp
@smp: GET_DATA_&side Asrc,Dfor,Dtmp
add.w #$8000,Dfor
10: move.w Dfor,Ddat ;Dfor>=Rbak Dfor<Rbak
sub.w Rbak,Ddat ;Dfor-Rbak Dfor-Rbak+65536
subx.w Dtmp,Dtmp ;0 -1
mulu.w Dscnt,Ddat ;(Dfor-Rbak)*RATE*65536 (Dfor-Rbak+65536)*RATE*65536
and.w Dscnt,Dtmp ;0 RATE*65536
swap.w Ddat ;(Dfor-Rbak)*RATE (Dfor-Rbak+65536)*RATE
sub.w Dtmp,Ddat ;(Dfor-Rbak)*RATE (Dfor-Rbak)*RATE
add.w Rbak,Ddat ;Rbak+(Dfor-Rbak)*RATE Rbak+(Dfor-Rbak)*RATE
sub.w #$8000,Ddat
blo @nmm
beq @nmz
@xpp: st.b (Adst)+
if side,<addq.l #1,Adst>
bra @vpp
@nmz: move.b #$7F,(Adst)+
if side,<addq.l #1,Adst>
bra @vmp
@epp: lea.l (@spp,pc),Ajmp
bra @done
@epm: lea.l (@spm,pc),Ajmp
bra @done
@emm: lea.l (@smm,pc),Ajmp
bra @done
@emp: lea.l (@smp,pc),Ajmp
bra @done
@done:
.endm
PRECONV_EXIT_UP_HQ .macro side
move.l Ajmp,preconv_jmp_&side
move.w Rpre,preconv_pre_&side
move.w Dscnt,preconv_scnt_&side+2
move.w Dfor,preconv_for_&side
move.w Rbak,preconv_bak_&side
.endm
;----------------------------------------------------------------
;<High Quality>
;間隔が伸びる→周波数が下がる
; side 0=Mono,1=StereoLeft,2=StereoRight
;Ddat dn
;Dfor dn
;Rpre dn/an
;Rbak dn/an
;Dtmp dn
;Dscnt dn
;Atbl an
;Asrc an
;Adst an
;Ajmp an
;Rsone dn/an const
;Rsrat dn/an
;Alim dn/an
PRECONV_DOWN_HQ .macro side
move.w preconv_for_&side,Dfor
move.w preconv_bak_&side,Rbak
move.l preconv_scnt_&side,Dscnt
move.w preconv_pre_&side,Rpre
move.l preconv_jmp_&side,Ajmp
move.l speed_rate,Rsrat
move.l #65536,Rsone
move.l Ajmp,Dtmp
beq @spp
jmp (Ajmp)
@npp: move.b #$7F,(Adst)+
if side,<addq.l #1,Adst>
bra @vpp
@dpp: move.b (Atbl,Rpre.w),(Adst)+
if side,<addq.l #1,Adst>
@vpp: move.w Ddat,Rpre
10: move.w Dfor,Rbak
cmp.l Alim,Asrc
bhs @epp
@spp: GET_DATA_&side Asrc,Dfor,Dtmp
add.w #$8000,Dfor
sub.l Rsone,Dscnt
bpl 10b
add.l Rsrat,Dscnt
move.w Dfor,Ddat ;Dfor>=Rbak Dfor<Rbak
sub.w Rbak,Ddat ;Dfor-Rbak Dfor-Rbak+65536
subx.w Dtmp,Dtmp ;0 -1
mulu.w Dscnt,Ddat ;(Dfor-Rbak)*RATE*65536 (Dfor-Rbak+65536)*RATE*65536
and.w Dscnt,Dtmp ;0 RATE*65536
swap.w Ddat ;(Dfor-Rbak)*RATE (Dfor-Rbak+65536)*RATE
sub.w Dtmp,Ddat ;(Dfor-Rbak)*RATE (Dfor-Rbak)*RATE
add.w Rbak,Ddat ;Rbak+(Dfor-Rbak)*RATE Rbak+(Dfor-Rbak)*RATE
sub.w #$8000,Ddat
bhi @dpp
beq @dpm
move.w Ddat,Dtmp
add.w Rpre,Dtmp
blt @xmm
@dpm: move.b (Atbl,Rpre.w),(Adst)+
if side,<addq.l #1,Adst>
@vpm: move.w Ddat,Rpre
10: move.w Dfor,Rbak
cmp.l Alim,Asrc
bhs @epm
@spm: GET_DATA_&side Asrc,Dfor,Dtmp
add.w #$8000,Dfor
sub.l Rsone,Dscnt
bpl 10b
add.l Rsrat,Dscnt
move.w Dfor,Ddat ;Dfor>=Rbak Dfor<Rbak
sub.w Rbak,Ddat ;Dfor-Rbak Dfor-Rbak+65536
subx.w Dtmp,Dtmp ;0 -1
mulu.w Dscnt,Ddat ;(Dfor-Rbak)*RATE*65536 (Dfor-Rbak+65536)*RATE*65536
and.w Dscnt,Dtmp ;0 RATE*65536
swap.w Ddat ;(Dfor-Rbak)*RATE (Dfor-Rbak+65536)*RATE
sub.w Dtmp,Ddat ;(Dfor-Rbak)*RATE (Dfor-Rbak)*RATE
add.w Rbak,Ddat ;Rbak+(Dfor-Rbak)*RATE Rbak+(Dfor-Rbak)*RATE
sub.w #$8000,Ddat
bhi @npp
beq @npz
@xmm: st.b (Adst)+
if side,<addq.l #1,Adst>
bra @vmm
@npz: move.b #$7F,(Adst)+
if side,<addq.l #1,Adst>
bra @vpm
@nmm: move.b #$7F,(Adst)+
if side,<addq.l #1,Adst>
bra @vmm
@dmm: move.b (Atbl,Rpre.w),(Adst)+
if side,<addq.l #1,Adst>
@vmm: move.w Ddat,Rpre
10: move.w Dfor,Rbak
cmp.l Alim,Asrc
bhs @emm
@smm: GET_DATA_&side Asrc,Dfor,Dtmp
add.w #$8000,Dfor
sub.l Rsone,Dscnt
bpl 10b
add.l Rsrat,Dscnt
move.w Dfor,Ddat ;Dfor>=Rbak Dfor<Rbak
sub.w Rbak,Ddat ;Dfor-Rbak Dfor-Rbak+65536
subx.w Dtmp,Dtmp ;0 -1
mulu.w Dscnt,Ddat ;(Dfor-Rbak)*RATE*65536 (Dfor-Rbak+65536)*RATE*65536
and.w Dscnt,Dtmp ;0 RATE*65536
swap.w Ddat ;(Dfor-Rbak)*RATE (Dfor-Rbak+65536)*RATE
sub.w Dtmp,Ddat ;(Dfor-Rbak)*RATE (Dfor-Rbak)*RATE
add.w Rbak,Ddat ;Rbak+(Dfor-Rbak)*RATE Rbak+(Dfor-Rbak)*RATE
sub.w #$8000,Ddat
blo @dmm
beq @dmp
move.w Ddat,Dtmp
add.w Rpre,Dtmp
bgt @xpp
@dmp: move.b (Atbl,Rpre.w),(Adst)+
if side,<addq.l #1,Adst>
@vmp: move.w Ddat,Rpre
10: move.w Dfor,Rbak
cmp.l Alim,Asrc
bhs @emp
@smp: GET_DATA_&side Asrc,Dfor,Dtmp
add.w #$8000,Dfor
sub.l Rsone,Dscnt
bpl 10b
add.l Rsrat,Dscnt
move.w Dfor,Ddat ;Dfor>=Rbak Dfor<Rbak
sub.w Rbak,Ddat ;Dfor-Rbak Dfor-Rbak+65536
subx.w Dtmp,Dtmp ;0 -1
mulu.w Dscnt,Ddat ;(Dfor-Rbak)*RATE*65536 (Dfor-Rbak+65536)*RATE*65536
and.w Dscnt,Dtmp ;0 RATE*65536
swap.w Ddat ;(Dfor-Rbak)*RATE (Dfor-Rbak+65536)*RATE
sub.w Dtmp,Ddat ;(Dfor-Rbak)*RATE (Dfor-Rbak)*RATE
add.w Rbak,Ddat ;Rbak+(Dfor-Rbak)*RATE Rbak+(Dfor-Rbak)*RATE
sub.w #$8000,Ddat
blo @nmm
beq @nmz
@xpp: st.b (Adst)+
if side,<addq.l #1,Adst>
bra @vpp
@nmz: move.b #$7F,(Adst)+
if side,<addq.l #1,Adst>
bra @vmp
@epp: lea.l (@spp,pc),Ajmp
bra @done
@epm: lea.l (@spm,pc),Ajmp
bra @done
@emm: lea.l (@smm,pc),Ajmp
bra @done
@emp: lea.l (@smp,pc),Ajmp
bra @done
@done:
.endm
PRECONV_EXIT_DOWN_HQ .macro side
move.l Ajmp,preconv_jmp_&side
move.w Rpre,preconv_pre_&side
move.l Dscnt,preconv_scnt_&side
move.w Dfor,preconv_for_&side
move.w Rbak,preconv_bak_&side
.endm
;----------------------------------------------------------------
;----------------------------------------------------------------
;<Super Quality>
;間隔が縮む→周波数が上がる
; side 0=Mono,1=StereoLeft,2=StereoRight
;Ddat dn
;Dfor dn
;Rpre dn/an
;Rbak dn/an
;Dtmp dn
;Dscnt dn
;Dtop dn sq only
;Atbl an
;Asrc an
;Adst an
;Ajmp an
;Rsrat dn/an
;Alim dn/an
PRECONV_UP_SQ .macro side
move.l preconv_dat_&side,Ddat
move.w preconv_for_&side,Dfor
move.w preconv_bak_&side,Rbak
move.w preconv_scnt_&side+2,Dscnt
move.w preconv_pre_&side,Rpre
move.l preconv_jmp_&side,Ajmp
move.w speed_rate+2,Rsrat
move.l Ajmp,Dtmp
beq @spp
jmp (Ajmp)
@npp: move.b #$7F,(Adst)+
if side,<addq.l #1,Adst>
bra @vpp
@dpp: move.b (Atbl,Rpre.w),(Adst)+
if side,<addq.l #1,Adst>
@vpp: move.w Ddat,Rpre
add.w Rsrat,Dscnt
bcs 11f
;2区間にまたがらない
move.w Dtop,Ddat
move.w Dfor,Dtop ;Dfor
;Dfor>=Rbak Dfor<Rbak
sub.w Rbak,Dtop ;Dfor-Rbak Dfor-Rbak+65536
subx.w Dtmp,Dtmp ;0 -1
mulu.w Dscnt,Dtop ;(Dfor-Rbak)*RATE*65536 (Dfor-Rbak+65536)*RATE*65536
and.w Dscnt,Dtmp ;0 RATE*65536
swap.w Dtop ;(Dfor-Rbak)*RATE (Dfor-Rbak+65536)*RATE
sub.w Dtmp,Dtop ;(Dfor-Rbak)*RATE (Dfor-Rbak)*RATE
add.w Rbak,Dtop ;Rbak+(Dfor-Rbak)*RATE
add.w Dtop,Ddat
roxr.w #1,Ddat
bra 12f
;2区間にまたがる
11: move.w Dfor,Ddat
add.w Dtop,Ddat
roxr.w #1,Ddat ;(Dtop+Dfor)/2
move.w Rsrat,Dtmp
sub.w Dscnt,Dtmp ;(Rsrat.w-Dscnt.w).w
mulu.w Dtmp,Ddat ;(Dtop+Dfor)/2*(Rsrat.w-Dscnt.w).w
move.w Dfor,Rbak
cmp.l Alim,Asrc
bhs @epp
@spp: GET_DATA_&side Asrc,Dfor,Dtmp
add.w #$8000,Dfor
move.w Dfor,Dtop ;Dfor
;Dfor>=Rbak Dfor<Rbak
sub.w Rbak,Dtop ;Dfor-Rbak Dfor-Rbak+65536
subx.w Dtmp,Dtmp ;0 -1
mulu.w Dscnt,Dtop ;(Dfor-Rbak)*RATE*65536 (Dfor-Rbak+65536)*RATE*65536
and.w Dscnt,Dtmp ;0 RATE*65536
swap.w Dtop ;(Dfor-Rbak)*RATE (Dfor-Rbak+65536)*RATE
sub.w Dtmp,Dtop ;(Dfor-Rbak)*RATE (Dfor-Rbak)*RATE
add.w Rbak,Dtop ;Rbak+(Dfor-Rbak)*RATE
move.w Rbak,Dtmp
add.w Dtop,Dtmp
roxr.w #1,Dtmp ;(Rbak+Dtop)/2
mulu.w Dscnt,Dtmp ;(Rbak+Dtop)/2*Dscnt.w
add.l Dtmp,Ddat ;面積
move.w sq_n,Dtmp
lsr.l Dtmp,Ddat
mulu.w sq_inv,Ddat
moveq.l #14,Dtmp
lsr.l Dtmp,Ddat
12: sub.w #$8000,Ddat
bhi @dpp
beq @dpm
move.w Ddat,Dtmp
add.w Rpre,Dtmp
blt @xmm
@dpm: move.b (Atbl,Rpre.w),(Adst)+
if side,<addq.l #1,Adst>
@vpm: move.w Ddat,Rpre
add.w Rsrat,Dscnt
bcs 11f
;2区間にまたがらない
move.w Dtop,Ddat
move.w Dfor,Dtop ;Dfor
;Dfor>=Rbak Dfor<Rbak
sub.w Rbak,Dtop ;Dfor-Rbak Dfor-Rbak+65536
subx.w Dtmp,Dtmp ;0 -1
mulu.w Dscnt,Dtop ;(Dfor-Rbak)*RATE*65536 (Dfor-Rbak+65536)*RATE*65536
and.w Dscnt,Dtmp ;0 RATE*65536
swap.w Dtop ;(Dfor-Rbak)*RATE (Dfor-Rbak+65536)*RATE
sub.w Dtmp,Dtop ;(Dfor-Rbak)*RATE (Dfor-Rbak)*RATE
add.w Rbak,Dtop ;Rbak+(Dfor-Rbak)*RATE
add.w Dtop,Ddat
roxr.w #1,Ddat
bra 12f
;2区間にまたがる
11: move.w Dfor,Ddat
add.w Dtop,Ddat
roxr.w #1,Ddat ;(Dtop+Dfor)/2
move.w Rsrat,Dtmp
sub.w Dscnt,Dtmp ;(Rsrat.w-Dscnt.w).w
mulu.w Dtmp,Ddat ;(Dtop+Dfor)/2*(Rsrat.w-Dscnt.w).w
move.w Dfor,Rbak
cmp.l Alim,Asrc
bhs @epm
@spm: GET_DATA_&side Asrc,Dfor,Dtmp
add.w #$8000,Dfor
move.w Dfor,Dtop ;Dfor
;Dfor>=Rbak Dfor<Rbak
sub.w Rbak,Dtop ;Dfor-Rbak Dfor-Rbak+65536
subx.w Dtmp,Dtmp ;0 -1
mulu.w Dscnt,Dtop ;(Dfor-Rbak)*RATE*65536 (Dfor-Rbak+65536)*RATE*65536
and.w Dscnt,Dtmp ;0 RATE*65536
swap.w Dtop ;(Dfor-Rbak)*RATE (Dfor-Rbak+65536)*RATE
sub.w Dtmp,Dtop ;(Dfor-Rbak)*RATE (Dfor-Rbak)*RATE
add.w Rbak,Dtop ;Rbak+(Dfor-Rbak)*RATE
move.w Rbak,Dtmp
add.w Dtop,Dtmp
roxr.w #1,Dtmp ;(Rbak+Dtop)/2
mulu.w Dscnt,Dtmp ;(Rbak+Dtop)/2*Dscnt.w
add.l Dtmp,Ddat ;面積
move.w sq_n,Dtmp
lsr.l Dtmp,Ddat
mulu.w sq_inv,Ddat
moveq.l #14,Dtmp
lsr.l Dtmp,Ddat
12: sub.w #$8000,Ddat
bhi @npp
beq @npz
@xmm: st.b (Adst)+
if side,<addq.l #1,Adst>
bra @vmm
@npz: move.b #$7F,(Adst)+
if side,<addq.l #1,Adst>
bra @vpm
@nmm: move.b #$7F,(Adst)+
if side,<addq.l #1,Adst>
bra @vmm
@dmm: move.b (Atbl,Rpre.w),(Adst)+
if side,<addq.l #1,Adst>
@vmm: move.w Ddat,Rpre
add.w Rsrat,Dscnt
bcs 11f
;2区間にまたがらない
move.w Dtop,Ddat
move.w Dfor,Dtop ;Dfor
;Dfor>=Rbak Dfor<Rbak
sub.w Rbak,Dtop ;Dfor-Rbak Dfor-Rbak+65536
subx.w Dtmp,Dtmp ;0 -1
mulu.w Dscnt,Dtop ;(Dfor-Rbak)*RATE*65536 (Dfor-Rbak+65536)*RATE*65536
and.w Dscnt,Dtmp ;0 RATE*65536
swap.w Dtop ;(Dfor-Rbak)*RATE (Dfor-Rbak+65536)*RATE
sub.w Dtmp,Dtop ;(Dfor-Rbak)*RATE (Dfor-Rbak)*RATE
add.w Rbak,Dtop ;Rbak+(Dfor-Rbak)*RATE
add.w Dtop,Ddat
roxr.w #1,Ddat
bra 12f
;2区間にまたがる
11: move.w Dfor,Ddat
add.w Dtop,Ddat
roxr.w #1,Ddat ;(Dtop+Dfor)/2
move.w Rsrat,Dtmp
sub.w Dscnt,Dtmp ;(Rsrat.w-Dscnt.w).w
mulu.w Dtmp,Ddat ;(Dtop+Dfor)/2*(Rsrat.w-Dscnt.w).w
move.w Dfor,Rbak
cmp.l Alim,Asrc
bhs @emm
@smm: GET_DATA_&side Asrc,Dfor,Dtmp
add.w #$8000,Dfor
move.w Dfor,Dtop ;Dfor
;Dfor>=Rbak Dfor<Rbak
sub.w Rbak,Dtop ;Dfor-Rbak Dfor-Rbak+65536
subx.w Dtmp,Dtmp ;0 -1
mulu.w Dscnt,Dtop ;(Dfor-Rbak)*RATE*65536 (Dfor-Rbak+65536)*RATE*65536
and.w Dscnt,Dtmp ;0 RATE*65536
swap.w Dtop ;(Dfor-Rbak)*RATE (Dfor-Rbak+65536)*RATE
sub.w Dtmp,Dtop ;(Dfor-Rbak)*RATE (Dfor-Rbak)*RATE
add.w Rbak,Dtop ;Rbak+(Dfor-Rbak)*RATE
move.w Rbak,Dtmp
add.w Dtop,Dtmp
roxr.w #1,Dtmp ;(Rbak+Dtop)/2
mulu.w Dscnt,Dtmp ;(Rbak+Dtop)/2*Dscnt.w
add.l Dtmp,Ddat ;面積
move.w sq_n,Dtmp
lsr.l Dtmp,Ddat
mulu.w sq_inv,Ddat
moveq.l #14,Dtmp
lsr.l Dtmp,Ddat
12: sub.w #$8000,Ddat
blo @dmm
beq @dmp
move.w Ddat,Dtmp
add.w Rpre,Dtmp
bgt @xpp
@dmp: move.b (Atbl,Rpre.w),(Adst)+
if side,<addq.l #1,Adst>
@vmp: move.w Ddat,Rpre
add.w Rsrat,Dscnt
bcs 11f
;2区間にまたがらない
move.w Dtop,Ddat
move.w Dfor,Dtop ;Dfor
;Dfor>=Rbak Dfor<Rbak
sub.w Rbak,Dtop ;Dfor-Rbak Dfor-Rbak+65536
subx.w Dtmp,Dtmp ;0 -1
mulu.w Dscnt,Dtop ;(Dfor-Rbak)*RATE*65536 (Dfor-Rbak+65536)*RATE*65536
and.w Dscnt,Dtmp ;0 RATE*65536
swap.w Dtop ;(Dfor-Rbak)*RATE (Dfor-Rbak+65536)*RATE
sub.w Dtmp,Dtop ;(Dfor-Rbak)*RATE (Dfor-Rbak)*RATE
add.w Rbak,Dtop ;Rbak+(Dfor-Rbak)*RATE
add.w Dtop,Ddat
roxr.w #1,Ddat
bra 12f
;2区間にまたがる
11: move.w Dfor,Ddat
add.w Dtop,Ddat
roxr.w #1,Ddat ;(Dtop+Dfor)/2
move.w Rsrat,Dtmp
sub.w Dscnt,Dtmp ;(Rsrat.w-Dscnt.w).w
mulu.w Dtmp,Ddat ;(Dtop+Dfor)/2*(Rsrat.w-Dscnt.w).w
move.w Dfor,Rbak
cmp.l Alim,Asrc
bhs @emp
@smp: GET_DATA_&side Asrc,Dfor,Dtmp
add.w #$8000,Dfor
move.w Dfor,Dtop ;Dfor
;Dfor>=Rbak Dfor<Rbak
sub.w Rbak,Dtop ;Dfor-Rbak Dfor-Rbak+65536
subx.w Dtmp,Dtmp ;0 -1
mulu.w Dscnt,Dtop ;(Dfor-Rbak)*RATE*65536 (Dfor-Rbak+65536)*RATE*65536
and.w Dscnt,Dtmp ;0 RATE*65536
swap.w Dtop ;(Dfor-Rbak)*RATE (Dfor-Rbak+65536)*RATE
sub.w Dtmp,Dtop ;(Dfor-Rbak)*RATE (Dfor-Rbak)*RATE
add.w Rbak,Dtop ;Rbak+(Dfor-Rbak)*RATE
move.w Rbak,Dtmp
add.w Dtop,Dtmp
roxr.w #1,Dtmp ;(Rbak+Dtop)/2
mulu.w Dscnt,Dtmp ;(Rbak+Dtop)/2*Dscnt.w
add.l Dtmp,Ddat ;面積
move.w sq_n,Dtmp
lsr.l Dtmp,Ddat
mulu.w sq_inv,Ddat
moveq.l #14,Dtmp
lsr.l Dtmp,Ddat
12: sub.w #$8000,Ddat
blo @nmm
beq @nmz
@xpp: st.b (Adst)+
if side,<addq.l #1,Adst>
bra @vpp
@nmz: move.b #$7F,(Adst)+
if side,<addq.l #1,Adst>
bra @vmp
@epp: lea.l (@spp,pc),Ajmp
bra @done
@epm: lea.l (@spm,pc),Ajmp
bra @done
@emm: lea.l (@smm,pc),Ajmp
bra @done
@emp: lea.l (@smp,pc),Ajmp
bra @done
@done:
.endm
PRECONV_EXIT_UP_SQ .macro side
move.l Ajmp,preconv_jmp_&side
move.w Rpre,preconv_pre_&side
move.w Dscnt,preconv_scnt_&side+2
move.w Dfor,preconv_for_&side
move.w Rbak,preconv_bak_&side
move.l Ddat,preconv_dat_&side
.endm
;----------------------------------------------------------------
;<Super Quality>
;間隔が伸びる→周波数が下がる
; side 0=Mono,1=StereoLeft,2=StereoRight
;Ddat dn
;Dfor dn
;Rpre dn/an
;Rbak dn/an
;Dtmp dn
;Dscnt dn
;Dtop dn sq only
;Atbl an
;Asrc an
;Adst an
;Ajmp an
;Rsone dn/an const
;Rsrat dn/an
;Alim dn/an
PRECONV_DOWN_SQ .macro side
move.l preconv_dat_&side,Ddat
move.w preconv_for_&side,Dfor
move.w preconv_bak_&side,Rbak
move.l preconv_scnt_&side,Dscnt
move.w preconv_pre_&side,Rpre
move.l preconv_jmp_&side,Ajmp
move.l speed_rate,Rsrat
move.l #65536,Rsone
move.l Ajmp,Dtmp
beq @spp
jmp (Ajmp)
@npp: move.b #$7F,(Adst)+
if side,<addq.l #1,Adst>
bra @vpp
@dpp: move.b (Atbl,Rpre.w),(Adst)+
if side,<addq.l #1,Adst>
@vpp: move.w Ddat,Rpre
move.w Dfor,Ddat
add.w Dtop,Ddat
roxr.w #1,Ddat ;(Dtop+Dfor)/2
move.w Dscnt,Dtmp
neg.w Dtmp ;65536-Dscnt.w
bne 21f
swap.w Ddat
clr.w Ddat
bra 22f
21: mulu.w Dtmp,Ddat ;(Dtop+Dfor)/2*(65536-Dscnt.w)
22: move.w sq_n_16,Dtmp
lsr.l Dtmp,Ddat ;(Dtop+Dfor)/2*(65536-Dscnt.w)>>sq_n_16
add.l Rsrat,Dscnt
sub.l Rsone,Dscnt
bmi 12f
11: move.w Dfor,Rbak
cmp.l Alim,Asrc
bhs @epp
@spp: GET_DATA_&side Asrc,Dfor,Dtmp
add.w #$8000,Dfor
move.w Dfor,Dtmp
add.w Rbak,Dtmp
roxr.w #1,Dtmp ;(Rbak+Dfor)/2
swap.w Dtmp
clr.w Dtmp
move.w sq_n_16,Rbak
lsr.l Rbak,Dtmp ;(Rbak+Dfor)/2*65536>>sq_n_16
add.l Dtmp,Ddat
sub.l Rsone,Dscnt
bpl 11b
12: move.w Dfor,Rbak
cmp.l Alim,Asrc
bhs @fpp
@upp: GET_DATA_&side Asrc,Dfor,Dtmp
add.w #$8000,Dfor
move.w Dfor,Dtop ;Dfor
;Dfor>=Rbak Dfor<Rbak
sub.w Rbak,Dtop ;Dfor-Rbak Dfor-Rbak+65536
subx.w Dtmp,Dtmp ;0 -1
mulu.w Dscnt,Dtop ;(Dfor-Rbak)*RATE*65536 (Dfor-Rbak+65536)*RATE*65536
and.w Dscnt,Dtmp ;0 RATE*65536
swap.w Dtop ;(Dfor-Rbak)*RATE (Dfor-Rbak+65536)*RATE
sub.w Dtmp,Dtop ;(Dfor-Rbak)*RATE (Dfor-Rbak)*RATE
add.w Rbak,Dtop ;Rbak+(Dfor-Rbak)*RATE
move.w Dtop,Dtmp
add.w Rbak,Dtmp
roxr.w #1,Dtmp ;(Rbak+Dtop)/2
mulu.w Dscnt,Dtmp ;(Rbak+Dtop)/2*Dscnt.w
move.w sq_n_16,Rbak
lsr.l Rbak,Dtmp ;(Rbak+Dfor)/2*Dscnt.w>>sq_n_16
add.l Dtmp,Ddat
swap.w Ddat
mulu.w sq_inv,Ddat
moveq.l #14,Dtmp
lsr.l Dtmp,Ddat
sub.w #$8000,Ddat
bhi @dpp
beq @dpm
move.w Ddat,Dtmp
add.w Rpre,Dtmp
blt @xmm
@dpm: move.b (Atbl,Rpre.w),(Adst)+
if side,<addq.l #1,Adst>
@vpm: move.w Ddat,Rpre
move.w Dfor,Ddat
add.w Dtop,Ddat
roxr.w #1,Ddat ;(Dtop+Dfor)/2
move.w Dscnt,Dtmp
neg.w Dtmp ;65536-Dscnt.w
bne 21f
swap.w Ddat
clr.w Ddat
bra 22f
21: mulu.w Dtmp,Ddat ;(Dtop+Dfor)/2*(65536-Dscnt.w)
22: move.w sq_n_16,Dtmp
lsr.l Dtmp,Ddat ;(Dtop+Dfor)/2*(65536-Dscnt.w)>>sq_n_16
add.l Rsrat,Dscnt
sub.l Rsone,Dscnt
bmi 12f
11: move.w Dfor,Rbak
cmp.l Alim,Asrc
bhs @epm
@spm: GET_DATA_&side Asrc,Dfor,Dtmp
add.w #$8000,Dfor
move.w Dfor,Dtmp
add.w Rbak,Dtmp
roxr.w #1,Dtmp ;(Rbak+Dfor)/2
swap.w Dtmp
clr.w Dtmp
move.w sq_n_16,Rbak
lsr.l Rbak,Dtmp ;(Rbak+Dfor)/2*65536>>sq_n_16
add.l Dtmp,Ddat
sub.l Rsone,Dscnt
bpl 11b
12: move.w Dfor,Rbak
cmp.l Alim,Asrc
bhs @fpm
@upm: GET_DATA_&side Asrc,Dfor,Dtmp
add.w #$8000,Dfor
move.w Dfor,Dtop ;Dfor
;Dfor>=Rbak Dfor<Rbak
sub.w Rbak,Dtop ;Dfor-Rbak Dfor-Rbak+65536
subx.w Dtmp,Dtmp ;0 -1
mulu.w Dscnt,Dtop ;(Dfor-Rbak)*RATE*65536 (Dfor-Rbak+65536)*RATE*65536
and.w Dscnt,Dtmp ;0 RATE*65536
swap.w Dtop ;(Dfor-Rbak)*RATE (Dfor-Rbak+65536)*RATE
sub.w Dtmp,Dtop ;(Dfor-Rbak)*RATE (Dfor-Rbak)*RATE
add.w Rbak,Dtop ;Rbak+(Dfor-Rbak)*RATE
move.w Dtop,Dtmp
add.w Rbak,Dtmp
roxr.w #1,Dtmp ;(Rbak+Dtop)/2
mulu.w Dscnt,Dtmp ;(Rbak+Dtop)/2*Dscnt.w
move.w sq_n_16,Rbak
lsr.l Rbak,Dtmp ;(Rbak+Dfor)/2*Dscnt.w>>sq_n_16
add.l Dtmp,Ddat
swap.w Ddat
mulu.w sq_inv,Ddat
moveq.l #14,Dtmp
lsr.l Dtmp,Ddat
sub.w #$8000,Ddat
bhi @npp
beq @npz
@xmm: st.b (Adst)+
if side,<addq.l #1,Adst>
bra @vmm
@npz: move.b #$7F,(Adst)+
if side,<addq.l #1,Adst>
bra @vpm
@nmm: move.b #$7F,(Adst)+
if side,<addq.l #1,Adst>
bra @vmm
@dmm: move.b (Atbl,Rpre.w),(Adst)+
if side,<addq.l #1,Adst>
@vmm: move.w Ddat,Rpre
move.w Dfor,Ddat
add.w Dtop,Ddat
roxr.w #1,Ddat ;(Dtop+Dfor)/2
move.w Dscnt,Dtmp
neg.w Dtmp ;65536-Dscnt.w
bne 21f
swap.w Ddat
clr.w Ddat
bra 22f
21: mulu.w Dtmp,Ddat ;(Dtop+Dfor)/2*(65536-Dscnt.w)
22: move.w sq_n_16,Dtmp
lsr.l Dtmp,Ddat ;(Dtop+Dfor)/2*(65536-Dscnt.w)>>sq_n_16
add.l Rsrat,Dscnt
sub.l Rsone,Dscnt
bmi 12f
11: move.w Dfor,Rbak
cmp.l Alim,Asrc
bhs @emm
@smm: GET_DATA_&side Asrc,Dfor,Dtmp
add.w #$8000,Dfor
move.w Dfor,Dtmp
add.w Rbak,Dtmp
roxr.w #1,Dtmp ;(Rbak+Dfor)/2
swap.w Dtmp
clr.w Dtmp
move.w sq_n_16,Rbak
lsr.l Rbak,Dtmp ;(Rbak+Dfor)/2*65536>>sq_n_16
add.l Dtmp,Ddat
sub.l Rsone,Dscnt
bpl 11b
12: move.w Dfor,Rbak
cmp.l Alim,Asrc
bhs @fmm
@umm: GET_DATA_&side Asrc,Dfor,Dtmp
add.w #$8000,Dfor
move.w Dfor,Dtop ;Dfor
;Dfor>=Rbak Dfor<Rbak
sub.w Rbak,Dtop ;Dfor-Rbak Dfor-Rbak+65536
subx.w Dtmp,Dtmp ;0 -1
mulu.w Dscnt,Dtop ;(Dfor-Rbak)*RATE*65536 (Dfor-Rbak+65536)*RATE*65536
and.w Dscnt,Dtmp ;0 RATE*65536
swap.w Dtop ;(Dfor-Rbak)*RATE (Dfor-Rbak+65536)*RATE
sub.w Dtmp,Dtop ;(Dfor-Rbak)*RATE (Dfor-Rbak)*RATE
add.w Rbak,Dtop ;Rbak+(Dfor-Rbak)*RATE
move.w Dtop,Dtmp
add.w Rbak,Dtmp
roxr.w #1,Dtmp ;(Rbak+Dtop)/2
mulu.w Dscnt,Dtmp ;(Rbak+Dtop)/2*Dscnt.w
move.w sq_n_16,Rbak
lsr.l Rbak,Dtmp ;(Rbak+Dfor)/2*Dscnt.w>>sq_n_16
add.l Dtmp,Ddat
swap.w Ddat
mulu.w sq_inv,Ddat
moveq.l #14,Dtmp
lsr.l Dtmp,Ddat
sub.w #$8000,Ddat
blo @dmm
beq @dmp
move.w Ddat,Dtmp
add.w Rpre,Dtmp
bgt @xpp
@dmp: move.b (Atbl,Rpre.w),(Adst)+
if side,<addq.l #1,Adst>
@vmp: move.w Ddat,Rpre
move.w Dfor,Ddat
add.w Dtop,Ddat
roxr.w #1,Ddat ;(Dtop+Dfor)/2
move.w Dscnt,Dtmp
neg.w Dtmp ;65536-Dscnt.w
bne 21f
swap.w Ddat
clr.w Ddat
bra 22f
21: mulu.w Dtmp,Ddat ;(Dtop+Dfor)/2*(65536-Dscnt.w)
22: move.w sq_n_16,Dtmp
lsr.l Dtmp,Ddat ;(Dtop+Dfor)/2*(65536-Dscnt.w)>>sq_n_16
add.l Rsrat,Dscnt
sub.l Rsone,Dscnt
bmi 12f
11: move.w Dfor,Rbak
cmp.l Alim,Asrc
bhs @emp
@smp: GET_DATA_&side Asrc,Dfor,Dtmp
add.w #$8000,Dfor
move.w Dfor,Dtmp
add.w Rbak,Dtmp
roxr.w #1,Dtmp ;(Rbak+Dfor)/2
swap.w Dtmp
clr.w Dtmp
move.w sq_n_16,Rbak
lsr.l Rbak,Dtmp ;(Rbak+Dfor)/2*65536>>sq_n_16
add.l Dtmp,Ddat
sub.l Rsone,Dscnt
bpl 11b
12: move.w Dfor,Rbak
cmp.l Alim,Asrc
bhs @fmp
@ump: GET_DATA_&side Asrc,Dfor,Dtmp
add.w #$8000,Dfor
move.w Dfor,Dtop ;Dfor
;Dfor>=Rbak Dfor<Rbak
sub.w Rbak,Dtop ;Dfor-Rbak Dfor-Rbak+65536
subx.w Dtmp,Dtmp ;0 -1
mulu.w Dscnt,Dtop ;(Dfor-Rbak)*RATE*65536 (Dfor-Rbak+65536)*RATE*65536
and.w Dscnt,Dtmp ;0 RATE*65536
swap.w Dtop ;(Dfor-Rbak)*RATE (Dfor-Rbak+65536)*RATE
sub.w Dtmp,Dtop ;(Dfor-Rbak)*RATE (Dfor-Rbak)*RATE
add.w Rbak,Dtop ;Rbak+(Dfor-Rbak)*RATE
move.w Dtop,Dtmp
add.w Rbak,Dtmp
roxr.w #1,Dtmp ;(Rbak+Dtop)/2
mulu.w Dscnt,Dtmp ;(Rbak+Dtop)/2*Dscnt.w
move.w sq_n_16,Rbak
lsr.l Rbak,Dtmp ;(Rbak+Dfor)/2*Dscnt.w>>sq_n_16
add.l Dtmp,Ddat
swap.w Ddat
mulu.w sq_inv,Ddat
moveq.l #14,Dtmp
lsr.l Dtmp,Ddat
sub.w #$8000,Ddat
blo @nmm
beq @nmz
@xpp: st.b (Adst)+
if side,<addq.l #1,Adst>
bra @vpp
@nmz: move.b #$7F,(Adst)+
if side,<addq.l #1,Adst>
bra @vmp
@epp: lea.l (@spp,pc),Ajmp
bra @done
@epm: lea.l (@spm,pc),Ajmp
bra @done
@emm: lea.l (@smm,pc),Ajmp
bra @done
@emp: lea.l (@smp,pc),Ajmp
bra @done
@fpp: lea.l (@upp,pc),Ajmp
bra @done
@fpm: lea.l (@upm,pc),Ajmp
bra @done
@fmm: lea.l (@umm,pc),Ajmp
bra @done
@fmp: lea.l (@ump,pc),Ajmp
bra @done
@done:
.endm
PRECONV_EXIT_DOWN_SQ .macro side
move.l Ajmp,preconv_jmp_&side
move.w Rpre,preconv_pre_&side
move.l Dscnt,preconv_scnt_&side
move.w Dfor,preconv_for_&side
move.w Rbak,preconv_bak_&side
move.l Ddat,preconv_dat_&side
.endm
;----------------------------------------------------------------
;面積補間
;
;@srat(=speed_rate):入力サンプリング間隔を65536としたときの出力サンプリング間隔
; 65536よりも小さければサンプリング周波数が上がり,
; 65536よりも大きければサンプリング周波数が下がる
;@scnt:前の入力データの位置を0,次の入力データの位置を65536としたときの,
; 次の直線補間の位置
;@for:次の入力データ
;@bak:前の入力データ
;@top:次の直線補間データ
;@dat:次の出力データ
;@pre:前の出力データ
;
;nを次のように定める
; 2^(n-1)<=@srat<2^n
; sq_n=n
; sq_n_16=n-16
;n<=16のとき,@srat<65536であり,サンプリング間隔が縮む→周波数が上がる
;n>=17のとき,@srat>=65536であり,サンプリング間隔が伸びる→周波数が下がる
;
; 2^(n-1)<=@srat<2^nより
; 1/2<=@srat/2^n<1
; 2>=2^n/@srat>1
; 32768>=2^(n+14)/@srat>16384
;
;32768>=2^(n+14)/@srat>16384より,
;2^(n+14)/@sratを求めておいて逆数乗算に使用する
;この除算は演奏開始時に1回だけ行うので,浮動小数点演算による高精度の除算を使う
; sq_inv=2^(n+14)/@srat
;
;n<=16のとき@srat<65536であり,サンプリング間隔が縮む→周波数が上がる
; @pre=@dat
; @scnt.w+=@srat.w
;キャリが立たなかったとき→2区間にまたがらない
; @dat=@top
; @top=@bak+(@for-@bak)*@scnt.w/65536 ;直線補間
; @dat=(@dat+@top)/2 ;台形の面積
;キャリが立たったとき→2区間にまたがる
; @dat=(@top+@for)/2*(@srat.w-@scnt.w).w ;最初の台形の面積
; @bak=@for
; @for=次の入力データ
; @top=@bak+(@for-@bak)*@scnt.w/65536 ;直線補間
; @dat+=(@bak+@top)/2*@scnt.w ;最後の台形の面積
; 面積<@srat*65536<2^(16+n)より,
; 面積を右にnビットシフトして上位の16ビットだけ取り出す
; @dat>>=sq_n
; @dat*=sq_inv ;逆数乗算
; (面積*2^(-n))*(2^(n+14)/@srat)=面積*2^14/@srat=平均の高さ*2^14
; @dat>>=14 ;平均の高さ
;
;n>=17のとき@srat>=65536であり,サンプリング間隔が伸びる→周波数が下がる
;必ず2区間以上をまたぐ
; @pre=@dat
; @dat=(@top+@for)/2*(65536-@scnt.w)>>sq_n_16 ;最初の台形の面積
; @scnt.l+=@srat.l
; while((@scnt.l-=65536)>=0)
; @bak=@for
; @for=次の入力データ
; @dat+=(@bak+@for)/2*65536>>sq_n_16 ;途中の台形の面積
; endwhile
; @bak=@for
; @for=次の入力データ
; @top=@bak+(@for-@bak)*@scnt.w/65536 ;直線補間
; @dat+=(@bak+@top)/2*@scnt.w>>sq_n_16 ;最後の台形の面積
; この時点で@dat=面積/2^(n-16)=平均の高さ*@srat/2^(n-16)
; @dat/=65536
; @dat*=sq_inv
; @dat/65536*(2^(n+14)/@srat)
; =(平均の高さ*@srat/2^(n-16))/65536*(2^(n+14)/@srat)
; =平均の高さ*2^(16-n)*2^(-16)*2^(n+14)
; =平均の高さ*2^(14)
; @dat>>=14 ;平均の高さ